import frappe
import os
import re
import shutil
from theme.utils.html_block_utils import get_home_navigation_html, get_home_navigation_css, create_html_block
from theme.utils.workspace_utils import (
    backup_workspace, 
    restore_workspace_from_backup, 
    add_custom_block_to_workspace, 
    clean_workspace_elements
)
from theme.utils.workspace_shortcuts_utils import (
    import_workspace_shortcuts,
    remove_workspace_shortcuts
)
from theme.utils.architecture_menu_utils import (
    add_architecture_menu_item,
    remove_architecture_menu_item
)
from theme.utils.navbar_utils import (
    backup_navbar_help_dropdown,
    remove_help_dropdown_items,
    restore_navbar_help_dropdown_from_backup,
    clean_navbar_backup_files
)

def copy_logo_and_check():
    """
    复制 logo 文件并检查其存在性
    """
    erpnext_logo_path = frappe.get_app_path("erpnext", "public", "images", "erpnext-logo.svg")
    theme_logo_path = frappe.get_app_path("theme", "public", "images", "theme-custom-logo.svg")
    
    # 检查ERPNext logo文件是否存在
    if not os.path.exists(erpnext_logo_path):
        frappe.logger().error(f"ERPNext logo文件不存在: {erpnext_logo_path}")
        return False
        
    # 检查主题自定义logo文件是否存在  
    if not os.path.exists(theme_logo_path):
        frappe.logger().error(f"主题自定义logo文件不存在: {theme_logo_path}")
        return False
    
    return True


def after_install():
    """
    在 theme 应用安装后执行的函数
    1. 安全地修改 ERPNext 的 hooks.py 文件，将 app_name 和 app_title 分别改为 nextjia 和 NextJia
    2. 创建自定义 HTML 块记录
    3. 备份Home工作空间配置
    4. 清理Home工作空间元素（删除快捷方式、标题、空行、卡片等）
    5. 添加home代码块到工作空间
    """
    try:
        # 1. 执行品牌化配置
        setup_branding()
        
        # 2. 创建自定义 HTML 块记录
        create_home_html_block()
        
        # 3. 配置Home工作空间
        setup_home_workspace()
        
        # 4. 导入工作空间快捷方式
        import_workspace_shortcuts_on_install()
        
        # 5. 添加架构图菜单项
        add_architecture_menu_on_install()
        
        # 6. 定制帮助下拉菜单
        customize_help_dropdown_on_install()
        
        # 提交数据库事务
        frappe.db.commit()
        
        frappe.msgprint("✅ Theme Custom 安装完成，品牌化配置、导航块创建、工作空间配置和快捷方式导入成功！", alert=True)
        
    except Exception as e:
        # 回滚事务
        frappe.db.rollback()
        frappe.log_error(f"Theme Custom 安装过程中出现错误: {str(e)}")
        frappe.throw(f"安装过程中出现错误: {str(e)}")


def setup_branding():
    """
    设置品牌化配置
    1. 修改 ERPNext 的标题为 EhomeOps
    2. 修改 Frappe Framework 的标题为 NexBlock
    """
    # 1. 处理 ERPNext 品牌化
    setup_erpnext_branding()
    
    # 2. 处理 Frappe Framework 品牌化
    setup_frappe_branding()


def setup_erpnext_branding():
    """
    设置 ERPNext 品牌化配置
    """
    # 检查 ERPNext 应用是否存在
    if "erpnext" not in frappe.get_installed_apps():
        frappe.log_error("ERPNext 应用未安装，跳过品牌化配置")
        return
    
    # 获取 ERPNext hooks.py 文件的路径
    erpnext_hooks_path = os.path.join(
        frappe.get_app_path("erpnext"), "hooks.py"
    )
    
    # 检查文件是否存在
    if not os.path.exists(erpnext_hooks_path):
        frappe.log_error(f"ERPNext hooks.py 文件不存在: {erpnext_hooks_path}")
        return
    
    # 创建备份文件
    backup_path = erpnext_hooks_path + ".theme_backup"
    if not os.path.exists(backup_path):
        shutil.copy2(erpnext_hooks_path, backup_path)
        frappe.log_error(f"已创建 ERPNext hooks.py 备份文件: {backup_path}")
    
    # 读取文件内容
    with open(erpnext_hooks_path, 'r', encoding='utf-8') as file:
        content = file.read()
    
    # 使用正则表达式进行精确替换，避免误替换
    # 只替换 app_title，不修改 app_name（重要：app_name 是系统标识符，不能修改）
    app_title_pattern = r'^app_title\s*=\s*["\']ERPNext["\']'
    
    # 检查是否已经被修改过
    if 'app_title = "EhomeOps"' in content:
        print("📝 ERPNext 应用标题已经是 EhomeOps，跳过品牌化配置")
        return
    
    # 执行替换 - 修改标题和所有 logo 引用
    content = re.sub(app_title_pattern, 'app_title = "EhomeOps"', content, flags=re.MULTILINE)
    
    # 修改所有 logo 路径引用
    logo_patterns = [
        (r'app_logo_url\s*=\s*["\'][^"\']*["\']', 'app_logo_url = "/assets/theme/images/nextjia-logo.svg"'),
        (r'"logo":\s*["\'][^"\']*erpnext-logo[^"\']*["\']', '"logo": "/assets/theme/images/nextjia-logo.svg"'),
        (r'"splash_image":\s*["\'][^"\']*erpnext-logo[^"\']*["\']', '"splash_image": "/assets/theme/images/nextjia-logo.svg"'),
        (r'email_brand_image\s*=\s*["\'][^"\']*erpnext-logo[^"\']*["\']', 'email_brand_image = "assets/theme/images/nextjia-logo.svg"'),
    ]
    
    for pattern, replacement in logo_patterns:
        content = re.sub(pattern, replacement, content)
    
    # 写回文件
    with open(erpnext_hooks_path, 'w', encoding='utf-8') as file:
        file.write(content)
    
    print("✅ 成功修改 ERPNext 应用标题和 Logo 为 EhomeOps 品牌")


def setup_frappe_branding():
    """
    设置 Frappe Framework 品牌化配置
    将 app_title 从 "Frappe Framework" 改为 "NexBlock"
    """
    # 获取 Frappe hooks.py 文件的路径
    frappe_hooks_path = os.path.join(
        frappe.get_app_path("frappe"), "hooks.py"
    )
    
    # 检查文件是否存在
    if not os.path.exists(frappe_hooks_path):
        frappe.log_error(f"Frappe hooks.py 文件不存在: {frappe_hooks_path}")
        return
    
    # 创建备份文件
    backup_path = frappe_hooks_path + ".theme_backup"
    if not os.path.exists(backup_path):
        shutil.copy2(frappe_hooks_path, backup_path)
        frappe.log_error(f"已创建 Frappe hooks.py 备份文件: {backup_path}")
    
    # 读取文件内容
    with open(frappe_hooks_path, 'r', encoding='utf-8') as file:
        content = file.read()
    
    # 使用正则表达式进行精确替换
    app_title_pattern = r'^app_title\s*=\s*["\']Frappe Framework["\']'
    
    # 检查是否已经被修改过
    if 'app_title = "NexBlock"' in content:
        print("📝 Frappe 应用标题已经是 NexBlock，跳过品牌化配置")
        return
    
    # 执行替换 - 修改标题
    content = re.sub(app_title_pattern, 'app_title = "NexBlock"', content, flags=re.MULTILINE)
    
    # 写回文件
    with open(frappe_hooks_path, 'w', encoding='utf-8') as file:
        file.write(content)
    
    print("✅ 成功修改 Frappe Framework 应用标题为 NexBlock")


def create_home_html_block():
    """
    创建主页导航 HTML 块记录
    使用分离的 HTML 和 CSS 文件
    """
    # 从文件中读取 HTML 和 CSS 内容
    home_html = get_home_navigation_html()
    home_css = get_home_navigation_css()
    
    # 检查内容是否成功读取
    if not home_html or not home_css:
        print("❌ 无法读取主页导航内容文件，跳过创建")
        return
    
    # 使用通用函数创建 HTML 块
    create_html_block(
        name="home",
        html_content=home_html,
        css_content=home_css,
        script_content="",  # 暂时不添加 JavaScript
        private=0  # 设为公开，所有用户可见
    )


def setup_home_workspace():
    """
    配置Home工作空间
    1. 备份当前配置
    2. 清理不需要的元素（快捷方式、标题、空行、卡片等）
    3. 添加home自定义块
    """
    try:
        print("🔧 开始配置Home工作空间...")
        
        # 1. 备份当前Home工作空间配置
        print("📋 备份Home工作空间配置...")
        backup_path = backup_workspace("Home")
        if not backup_path:
            print("⚠️ 备份失败，但继续执行配置")
        
        # 2. 清理工作空间元素，只保留html和custom_block类型
        print("🧹 清理Home工作空间元素...")
        clean_success = clean_workspace_elements(
            workspace_name="Home",
            keep_types=["html", "custom_block"]
        )
        
        if not clean_success:
            print("⚠️ 清理工作空间元素失败，但继续执行")
        
        # 3. 添加home自定义块到工作空间顶部
        print("➕ 添加home自定义块到工作空间...")
        add_success = add_custom_block_to_workspace(
            workspace_name="Home",
            block_name="home",
            position="top"
        )
        
        if add_success:
            print("✅ Home工作空间配置完成")
        else:
            print("⚠️ 添加自定义块失败")
        
        # 4. 执行数据迁移以确保更改生效
        print("🔄 执行数据迁移...")
        frappe.db.commit()
        
    except Exception as e:
        frappe.log_error(f"配置Home工作空间时出错: {str(e)}")
        print(f"❌ 配置Home工作空间失败: {str(e)}")
        raise Exception(f"配置Home工作空间时出错: {str(e)}")


def before_uninstall():
    """
    在 theme 应用卸载前执行的函数
    1. 恢复Home工作空间配置
    2. 删除安装时创建的 home HTML 块记录
    3. 安全地恢复 ERPNext 的 hooks.py 文件，将 app_name 和 app_title 恢复为原始值
    4. 安全地恢复 Frappe Framework 的 hooks.py 文件，将 app_title 恢复为原始值
    """
    try:
        # 1. 恢复Home工作空间配置
        restore_home_workspace()
        
        # 2. 删除 home HTML 块记录
        delete_home_html_block()
        
        # 3. 移除工作空间快捷方式
        remove_workspace_shortcuts_on_uninstall()
        
        # 4. 移除架构图菜单项
        remove_architecture_menu_on_uninstall()
        
        # 5. 恢复帮助下拉菜单
        restore_help_dropdown_on_uninstall()
        
        # 6. 恢复 ERPNext 品牌化配置
        restore_erpnext_branding()
        
        # 7. 恢复 Frappe Framework 品牌化配置
        restore_frappe_branding()
        
        # 提交数据库事务
        frappe.db.commit()
        
        frappe.msgprint("✅ Theme Custom 卸载完成，已清理所有相关数据并恢复原始配置！", alert=True)
        
    except Exception as e:
        # 回滚事务
        frappe.db.rollback()
        frappe.log_error(f"Theme Custom 卸载过程中出现错误: {str(e)}")
        frappe.throw(f"卸载过程中出现错误: {str(e)}")


def restore_home_workspace():
    """
    恢复Home工作空间配置
    从备份文件中恢复原始配置
    """
    try:
        print("🔄 开始恢复Home工作空间配置...")
        
        # 尝试从备份恢复Home工作空间
        restore_success = restore_workspace_from_backup("Home")
        
        if restore_success:
            print("✅ 成功恢复Home工作空间配置")
        else:
            print("⚠️ 未找到备份文件或恢复失败，跳过恢复")
        
        # 执行数据迁移以确保更改生效
        frappe.db.commit()
        
    except Exception as e:
        frappe.log_error(f"恢复Home工作空间配置时出错: {str(e)}")
        print(f"❌ 恢复Home工作空间配置失败: {str(e)}")
        # 不抛出异常，允许卸载继续进行


def delete_home_html_block():
    """
    删除安装时创建的 home HTML 块记录
    """
    try:
        # 检查 home HTML 块是否存在
        if frappe.db.exists("Custom HTML Block", "home"):
            # 删除记录
            frappe.delete_doc("Custom HTML Block", "home", ignore_permissions=True)
            print("✅ 成功删除 home HTML 块记录")
        else:
            print("📝 home HTML 块记录不存在，跳过删除")
            
    except Exception as e:
        frappe.log_error(f"删除 home HTML 块记录时出错: {str(e)}")
        print(f"❌ 删除 home HTML 块记录失败: {str(e)}")


def restore_erpnext_branding():
    """
    恢复 ERPNext 品牌化配置
    """
    try:
        # 检查 ERPNext 应用是否存在
        if "erpnext" not in frappe.get_installed_apps():
            frappe.log_error("ERPNext 应用未安装，跳过恢复操作")
            return
        
        # 获取 ERPNext hooks.py 文件的路径
        erpnext_hooks_path = os.path.join(
            frappe.get_app_path("erpnext"), "hooks.py"
        )
        backup_path = erpnext_hooks_path + ".theme_backup"
        
        # 优先使用备份文件恢复
        if os.path.exists(backup_path):
            shutil.copy2(backup_path, erpnext_hooks_path)
            os.remove(backup_path)  # 删除备份文件
            print("✅ 成功从备份文件恢复 ERPNext 应用名称为原始状态")
            return
        
        # 如果没有备份文件，则使用正则表达式恢复
        if not os.path.exists(erpnext_hooks_path):
            frappe.log_error(f"ERPNext hooks.py 文件不存在: {erpnext_hooks_path}")
            return
        
        # 读取文件内容
        with open(erpnext_hooks_path, 'r', encoding='utf-8') as file:
            content = file.read()
        
        # 检查是否需要恢复
        if 'app_title = "ERPNext"' in content:
            print("📝 ERPNext 应用标题已经是原始状态，无需恢复")
            return
        
        # 使用正则表达式进行精确恢复 - 恢复标题和所有 logo
        app_title_pattern = r'^app_title\s*=\s*["\']EhomeOps["\']'
        
        # 恢复所有 logo 路径引用
        logo_restore_patterns = [
            (r'app_logo_url\s*=\s*["\'][^"\']*theme[^"\']*["\']', 'app_logo_url = "/assets/erpnext/images/erpnext-logo.svg"'),
            (r'"logo":\s*["\'][^"\']*theme[^"\']*["\']', '"logo": "/assets/erpnext/images/erpnext-logo.svg"'),
            (r'"splash_image":\s*["\'][^"\']*theme[^"\']*["\']', '"splash_image": "/assets/erpnext/images/erpnext-logo.svg"'),
            (r'email_brand_image\s*=\s*["\'][^"\']*theme[^"\']*["\']', 'email_brand_image = "assets/erpnext/images/erpnext-logo.jpg"'),
        ]
        
        content = re.sub(app_title_pattern, 'app_title = "ERPNext"', content, flags=re.MULTILINE)
        
        for pattern, replacement in logo_restore_patterns:
            content = re.sub(pattern, replacement, content)
        
        # 写回文件
        with open(erpnext_hooks_path, 'w', encoding='utf-8') as file:
            file.write(content)
        
        print("✅ 成功恢复 ERPNext 应用标题和 Logo 为原始状态")
        
    except Exception as e:
        frappe.log_error(f"恢复 ERPNext hooks.py 文件时出错: {str(e)}")
        raise Exception(f"恢复 ERPNext 配置时出错: {str(e)}")


def restore_frappe_branding():
    """
    恢复 Frappe Framework 品牌化配置
    将 app_title 从 "NexBlock" 恢复为 "Frappe Framework"
    """
    try:
        # 获取 Frappe hooks.py 文件的路径
        frappe_hooks_path = os.path.join(
            frappe.get_app_path("frappe"), "hooks.py"
        )
        backup_path = frappe_hooks_path + ".theme_backup"
        
        # 优先使用备份文件恢复
        if os.path.exists(backup_path):
            shutil.copy2(backup_path, frappe_hooks_path)
            os.remove(backup_path)  # 删除备份文件
            print("✅ 成功从备份文件恢复 Frappe 应用标题为原始状态")
            return
        
        # 如果没有备份文件，则使用正则表达式恢复
        if not os.path.exists(frappe_hooks_path):
            frappe.log_error(f"Frappe hooks.py 文件不存在: {frappe_hooks_path}")
            return
        
        # 读取文件内容
        with open(frappe_hooks_path, 'r', encoding='utf-8') as file:
            content = file.read()
        
        # 检查是否需要恢复
        if 'app_title = "Frappe Framework"' in content:
            print("📝 Frappe 应用标题已经是原始状态，无需恢复")
            return
        
        # 使用正则表达式进行精确恢复 - 恢复标题
        app_title_pattern = r'^app_title\s*=\s*["\']NexBlock["\']'
        
        content = re.sub(app_title_pattern, 'app_title = "Frappe Framework"', content, flags=re.MULTILINE)
        
        # 写回文件
        with open(frappe_hooks_path, 'w', encoding='utf-8') as file:
            file.write(content)
        
        print("✅ 成功恢复 Frappe Framework 应用标题为原始状态")
        
    except Exception as e:
        frappe.log_error(f"恢复 Frappe hooks.py 文件时出错: {str(e)}")
        raise Exception(f"恢复 Frappe 配置时出错: {str(e)}")


def import_workspace_shortcuts_on_install():
    """
    安装时导入工作空间快捷方式
    """
    try:
        print("📋 开始导入工作空间快捷方式...")
        
        # 导入工作空间快捷方式
        success = import_workspace_shortcuts()
        
        if success:
            print("✅ 工作空间快捷方式导入完成")
        else:
            print("⚠️ 工作空间快捷方式导入部分失败，请检查日志")
        
    except Exception as e:
        frappe.log_error(f"安装时导入工作空间快捷方式出错: {str(e)}")
        print(f"❌ 导入工作空间快捷方式失败: {str(e)}")


def remove_workspace_shortcuts_on_uninstall():
    """
    卸载时移除工作空间快捷方式
    """
    try:
        print("🗑️ 开始移除工作空间快捷方式...")
        
        # 移除工作空间快捷方式
        success = remove_workspace_shortcuts()
        
        if success:
            print("✅ 工作空间快捷方式移除完成")
        else:
            print("⚠️ 工作空间快捷方式移除部分失败，请检查日志")
        
    except Exception as e:
        frappe.log_error(f"卸载时移除工作空间快捷方式出错: {str(e)}")
        print(f"❌ 移除工作空间快捷方式失败: {str(e)}")


def add_architecture_menu_on_install():
    """
    安装时添加架构图菜单项
    """
    try:
        print("📋 开始添加架构图菜单项...")
        
        # 添加架构图菜单项
        success = add_architecture_menu_item()
        
        if success:
            print("✅ 架构图菜单项添加完成")
        else:
            print("⚠️ 架构图菜单项添加失败，请检查日志")
        
    except Exception as e:
        frappe.log_error(f"安装时添加架构图菜单项出错: {str(e)}")
        print(f"❌ 添加架构图菜单项失败: {str(e)}")


def remove_architecture_menu_on_uninstall():
    """
    卸载时移除架构图菜单项
    """
    try:
        print("🗑️ 开始移除架构图菜单项...")
        
        # 移除架构图菜单项
        success = remove_architecture_menu_item()
        
        if success:
            print("✅ 架构图菜单项移除完成")
        else:
            print("⚠️ 架构图菜单项移除失败，请检查日志")
        
    except Exception as e:
        frappe.log_error(f"卸载时移除架构图菜单项出错: {str(e)}")
        print(f"❌ 移除架构图菜单项失败: {str(e)}")


def customize_help_dropdown_on_install():
    """
    安装时定制帮助下拉菜单
    删除指定的菜单项：Documentation, User Forum, Frappe School, Report an Issue, About
    """
    try:
        print("🎨 开始定制帮助下拉菜单...")
        
        # 要删除的菜单项 (更新为实际存在的项目)
        items_to_remove = [
            "About",
            "Frappe Support"
        ]
        
        # 1. 备份当前配置
        print("📋 备份当前帮助下拉菜单配置...")
        backup_path = backup_navbar_help_dropdown()
        
        if not backup_path:
            print("⚠️ 备份失败，但继续执行删除操作")
        
        # 2. 删除指定的菜单项
        print("🗑️ 删除指定的帮助菜单项...")
        success = remove_help_dropdown_items(items_to_remove)
        
        if success:
            print("✅ 帮助下拉菜单定制完成")
        else:
            print("⚠️ 帮助下拉菜单定制失败，请检查日志")
        
    except Exception as e:
        frappe.log_error(f"安装时定制帮助下拉菜单出错: {str(e)}")
        print(f"❌ 定制帮助下拉菜单失败: {str(e)}")


def restore_help_dropdown_on_uninstall():
    """
    卸载时恢复帮助下拉菜单
    """
    try:
        print("🔄 开始恢复帮助下拉菜单...")
        
        # 从备份恢复帮助下拉菜单
        success = restore_navbar_help_dropdown_from_backup()
        
        if success:
            print("✅ 帮助下拉菜单恢复完成")
        else:
            print("⚠️ 帮助下拉菜单恢复失败，请检查日志")
        
        # 清理备份文件
        print("🧹 清理navbar备份文件...")
        clean_navbar_backup_files()
        
    except Exception as e:
        frappe.log_error(f"卸载时恢复帮助下拉菜单出错: {str(e)}")
        print(f"❌ 恢复帮助下拉菜单失败: {str(e)}")